/*
 * @Copyright: (C) 2019 Zhang Rida. All rights reserved.
 *
 * @Author: Zhang Rida
 * @Email: 215154317@qq.com
 * @FilePath: /WEILA_SDK_MODULE/src/wlsdk/src/burst_media.h
 * @Date: 2021-02-27 17:08:35
 * @Description:
 *
 * @LastEditors: Zhang Rida
 * @LastEditTime: 2022-07-29 20:07:11
 */
#ifndef _BURST_MEDIA_H
#define _BURST_MEDIA_H

#include "wl_osal.h"

#ifdef __cplusplus
extern "C" {
#endif

#define BURST_FRAME_TIME 20  // 20ms
#define BURST_PTT_PACKAGE_FRAMES 25
#define BURST_VOIP_PACKAGE_FRAMES 10

#define OPUS_RATE 12000
#define OPUS_FRAME_LEN ((OPUS_RATE / 8) / 50)

typedef enum {
    BURST_MEDIA_TONE_BURST_START   = 0,
    BURST_MEDIA_TONE_BURST_STOP    = 1,
    BURST_MEDIA_TONE_LISTEN_START  = 2,
    BURST_MEDIA_TONE_LISTEN_STOP   = 3,
    BURST_MEDIA_TONE_OFFLINE       = 4,
    BURST_MEDIA_TONE_ALARM         = 5,
    BURST_MEDIA_TONE_DENY          = 6,
    BURST_MEDIA_TONE_VOIP_INCOMING = 7,
    BURST_MEDIA_TONE_VOIP_RING     = 8,
    BURST_MEDIA_TONE_VOIP_HANGUP   = 9,
    BURST_MEDIA_TONE_MAX
} burst_media_toneid;

//语音播放中,如果播放器优先级低于录音器,停止播放,如果优先级高于等于录音器,需要判断是否支持voip,不支持等语音播放完后再启动录音
//语音录音中,如果录音器优先级低于等于播放器,如果支持voip,录音播放同时进行,如果不支持voip,停止录音,优先播放
typedef enum {
    BURST_MEDIA_PRORITY_TEXT      = 4,
    BURST_MEDIA_PRORITY_AUDIO     = 4,
    BURST_MEDIA_PRORITY_PTT       = 4,
    BURST_MEDIA_PRORITY_TTS       = 8,
    BURST_MEDIA_PRORITY_REALTIME  = 9,
    BURST_MEDIA_PRORITY_PLAYBACK  = 10,
    BURST_MEDIA_PRORITY_ALARM     = 11,
    BURST_MEDIA_PRORITY_RECORD    = 16,
    BURST_MEDIA_PRORITY_MONITOR   = 17,
    BURST_MEDIA_PRORITY_VOIP_TONE = 20,  // voip提示音
    BURST_MEDIA_PRORITY_VOIP      = 21
} burst_msg_prority;

/**
 * @description: 录音器回调函数
 * @param marker 录音标记
 * @param frameslen 录音数据长度
 * @param frames 录音数据 帧结构 为LV结构 L:2byte帧长 V:Lbyte帧数剧
 * @param framecount 录音帧数
 * @param sessionid 录音sessionid
 * @param sessiontype 录音sessiontype
 * @param context 录音上下文
 * @return 无
 */
typedef void (*burst_media_recorder_callback)(wl_uint32 marker,
                                              wl_uint32 frameslen,
                                              wl_char*  frames,
                                              wl_uint32 framecount,
                                              wl_uint64 sessionid,
                                              wl_uint32 sessiontype,
                                              void*     context);

/**
 * @description: 播放器回调函数
 * @param playcount 播放帧数
 * @param context 播放器上下文
 * @return 无
 */
typedef void (*burst_media_player_callback)(wl_uint32 playcount, void* context);

/**
 * @description: 播放器回调函数
 * @param result 播放结束错误码
 * @param isclosed 是否已停止
 * @param context 播放器上下文
 * @return 无
 */
typedef void (*burst_media_end_callback)(wl_int32 result,
                                         wl_bool  isclosed,
                                         void*    context);  // result 0 正常结束 -1 异常结束

wl_int32 burst_media_init(void);
wl_int32 burst_media_end(void);

wl_bool burst_media_is_voip_support(void);

wl_int32 burst_media_set_record_drop_duration(wl_uint32 duration);

wl_int32 burst_media_set_record_end_drop_duration(wl_uint32 duration);

wl_int32 burst_media_start_voip(wl_uint64                     sessionid,
                                wl_uint32                     sessiontype,
                                burst_media_recorder_callback recorder_callback,
                                burst_media_end_callback      recorder_end_callback,
                                wl_uint32                     recorder_package_frames,
                                burst_media_player_callback   player_callback,
                                burst_media_end_callback      player_end_callback,
                                void*                         context);

wl_int32 burst_media_stop_voip(void);

wl_int32 burst_media_start_recorder(burst_media_recorder_callback callback,
                                    burst_media_end_callback      end_callback,
                                    wl_uint64                     sessionid,
                                    wl_uint32                     sessiontype,
                                    wl_int32                      prority,
                                    wl_uint32                     package_frames,
                                    void*                         context);

void burst_media_refresh_recorder_lifetime(wl_uint32 lifetime);  // lifetime单位ms

wl_int32 burst_media_stop_recorder(void);

wl_int32 burst_media_stop_recorder_audio(void);

/**
 * @description: 是否录音中
 * @param 无
 * @return wl_true
 */
wl_bool burst_media_is_recording(void);

wl_bool burst_media_is_record_session(wl_uint64 sessionid, wl_uint32 sessiontype);

wl_int32 burst_media_get_recorder_prority(void);

wl_int32 burst_media_start_player(burst_media_player_callback callback,
                                  burst_media_end_callback    end_callback,
                                  wl_int32                    prority,
                                  void*                       context);

wl_int32 burst_media_stop_player(void);

wl_int32 burst_media_stop_player_immediately(void);

/**
 * @description: 是否播放中
 * @param 无
 * @return wl_true
 */
wl_bool burst_media_is_playing(void);

wl_int32 burst_media_get_player_prority(void);

/**
 * @description: 播放器上下文
 * @param 无
 * @return context
 */
void* burst_media_get_player_context(void);

/**
 * @description: 已播放帧数
 * @param 无
 * @return 已播放帧数
 */
wl_uint32 burst_media_get_play_frames(void);

/**
 * @description: 剩余播放帧数
 * @param 无
 * @return 已播放帧数
 */
wl_uint32 burst_media_get_player_left_frames(void);

/**
 * @description: 播放器生命期
 * @param 无
 * @return <=0 播放器到期
 */
wl_int32 burst_media_get_player_lifeleft(void);

/**
 * @description: 设置播放器帧结束
 * @param 无
 * @return 0 成功 -1 失败
 */
wl_int32 burst_media_set_player_frame_end(void);

/**
 * @description: 添加播放数据
 * @param frames 录音数据 帧结构 为LV结构 L:2byte帧长 V:Lbyte帧数剧
 * @param framecount 录音帧数
 * @return 0 成功 -1 失败
 */
wl_int32 burst_media_add_play_audio(wl_char* frames, wl_uint32 framelen, wl_uint32 framecount);

/**
 * @description: 播放提示音
 * @param toneid 提示音id
 * @param end_callback 结束回调
 * @param prority 优先级
 * @param timeout 超时结束 单位ms 0一次播放 非0重复播放
 * @return 0 成功 -1 失败
 */
wl_int32 burst_media_play_tone(wl_uint32                toneid,
                               burst_media_end_callback end_callback,
                               wl_int32                 prority,
                               wl_int32                 timeout,
                               void*                    context);

/**
 * @description: 统计burst audio帧数据长度 burst_audio帧结构 head|len|data
 * @param burst_audio burst帧数据
 * @param burst_audio_len burst帧数据长度
 * @param media_audio_len media帧数据长度
 * @param frames_count 帧数
 * @return 等于0成功 小于0 burst_audio非法数据
 */
wl_int32 burst_media_count_burst_audio(wl_char*       burst_audio,
                                       wl_uint32      burst_audio_len,
                                       OUT wl_uint32* media_audio_len,
                                       OUT wl_uint32* frames_count);

/**
 * @description: 转换burst audio帧数据head|len|data为media_audio帧数据 len(short)|data
 * @param burst_audio burst帧数据
 * @param burst_audio_len burst帧数据长度
 * @param media_audio media帧数据
 * @param media_audio_len media帧数据长度
 * @return 等于0成功 小于0 burst_audio非法数据
 */
wl_int32 burst_media_convert_burst_audio_to_media_audio(wl_char*  burst_audio,
                                                        wl_uint32 burst_audio_len,
                                                        wl_char*  media_audio,
                                                        wl_uint32 media_audio_len);

/**
 * @description: 统计pcm_audio帧数据长度
 * @param pcm_audio_len pcm帧数据长度
 * @param pcm_audio_rate pcm帧码率
 * @param media_audio_len media帧数据长度
 * @param frames_count 帧数
 * @return 等于0成功 小于0 burst_audio非法数据
 */
wl_int32 burst_media_count_pcm_audio(wl_uint32      pcm_audio_len,
                                     wl_uint32      pcm_audio_rate,
                                     OUT wl_uint32* media_audio_len,
                                     OUT wl_uint32* frames_count);

/**
 * @description: 转换pcm帧数据为media_audio帧数据 len(short)|data
 * @param pcm_audio pcm帧数据
 * @param pcm_audio_len pcm帧数据长度
 * @param media_audio media帧数据
 * @param media_audio_len media帧数据长度
 * @return 等于0成功 小于0 pcm_audio非法数据
 */
wl_int32 burst_media_convert_pcm_audio_to_media_audio(wl_char*   pcm_audio,
                                                      wl_uint32  pcm_audio_len,
                                                      wl_uint32  pcm_rate,
                                                      wl_char*   media_audio,
                                                      wl_uint32* media_audio_len);

#ifdef __cplusplus
}
#endif
#endif
